package model;

import java.io.IOException;
import net.beadsproject.beads.core.AudioContext;
import net.beadsproject.beads.data.Sample;
import net.beadsproject.beads.data.SampleManager;
import net.beadsproject.beads.ugens.SamplePlayer;
import util.FileIO;
import util.PitchRatioCalculator;

/**
 * Holds data for different types of Instrument sounds and means of manipulating
 * them to attain the correct pitch.
 */
public enum Instrument {

	//"Fun" instruments
	MARIO("/data/sound/mario/musicnote2.wav", 87, 8, true),
	MUSHROOM("/data/sound/mario/musicnote3.wav", 87, 8, true),
	YOSHI("/data/sound/mario/musicnote4.wav", 87, 8, true),
	STAR("/data/sound/mario/musicnote5.wav", 87, 8, true),
	FLOWER("/data/sound/mario/musicnote6.wav", 87, 8, true),
	GAMEBOY("/data/sound/mario/musicnote7.wav", 87, 8, true),
	DOG("/data/sound/mario/musicnote8.wav", 87, 8, true),
	CAT("/data/sound/mario/musicnote9.wav", 87, 8, true),
	PIG("/data/sound/mario/musicnote10.wav", 87, 8, true),
	DUCK("/data/sound/mario/musicnote11.wav", 87, 8, true),
	FACE("/data/sound/mario/musicnote12.wav", 87, 8, true),
	PLANE("/data/sound/mario/musicnote13.wav", 87, 8, true),
	BOAT("/data/sound/mario/musicnote14.wav", 87, 8, true),
	CAR("/data/sound/mario/musicnote15.wav", 87, 8, true),
	HEART("/data/sound/mario/musicnote16.wav", 87, 8, true),

	//Standard Instruments
	PIANO("/data/sound/piano2.wav", 98, 7),
	CYMBAL("/data/sound/crash.wav", 98, 7),
	DRUM("/data/sound/drum3.wav", 98, 7),
	SYNTHESISER("/data/sound/synth.wav", 98, 7),
	HARP("/data/sound/harp2.wav", 98, 7),
	FLUTE("/data/sound/flute1.wav", 98, 7),
	BASS("/data/sound/bass.aif", 98, 7),
	BEEP("/data/sound/beep2.wav", 98, 7),
	SAXOPHONE("/data/sound/sax2.wav", 98, 7),
	XYLOPHONE("/data/sound/xyla2.wav", 98, 7),
	;

	private final Sample sample;			//Original sound file
	private final double initialFrequency;  //Original frequency
	private final int initialNote;          //Original note (see model.Sequence)
	private final boolean fun;              //"Fun" or Standard?

	private Instrument(String path, double initialFrequency, int initialNote) {
		this(path, initialFrequency, initialNote, false);
	}

	private Instrument(String path, double initialFrequency, int initialNote, boolean fun) {
		Sample tempSample = null;
		try {
			tempSample = SampleManager.sample(
				FileIO.getAbsolutePath(path)
			);
		} catch(IOException ioe) {
			System.out.println("FATAL ERROR: Could not find " + path);
			System.exit(-1);
		}

		this.sample = tempSample;
		this.initialFrequency = initialFrequency;
		this.initialNote = initialNote;
		this.fun = fun;
	}

	public boolean isFun() {
		return fun;
	}

	public SamplePlayer getSampleAtNote(AudioContext audioContext, int note) {
		SamplePlayer samplePlayer = new SamplePlayer(audioContext, sample);

		float playbackRate = PitchRatioCalculator.semitoneRatio(
			initialFrequency, (initialNote-note)*2
		);

		samplePlayer.getPitchUGen().setValue(playbackRate);
		samplePlayer.setKillOnEnd(true);

		return samplePlayer;
	}
}
